package com.atguigu.yygh.user.service.impl;

import com.atguigu.yygh.common.exception.YyghException;
import com.atguigu.yygh.common.util.JwtHelper;
import com.atguigu.yygh.enums.AuthStatusEnum;
import com.atguigu.yygh.enums.StatusEnum;
import com.atguigu.yygh.model.user.Patient;
import com.atguigu.yygh.model.user.UserInfo;
import com.atguigu.yygh.user.mapper.UserInfoMapper;
import com.atguigu.yygh.user.service.PatientService;
import com.atguigu.yygh.user.service.UserInfoService;
import com.atguigu.yygh.vo.user.LoginVo;
import com.atguigu.yygh.vo.user.UserAuthVo;
import com.atguigu.yygh.vo.user.UserInfoQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2022-08-31
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PatientService patientService;

    @Override
    public Map<String, Object> login(LoginVo loginVo) {
        // 1.获取用户的手机号和验证码信息
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();

        // 2.对手机号和验证码进行判空
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            throw new YyghException(20001, "手机号和验证码不能为空");
        }
        // 3.对验证进一步验证
        String redisCode = (String)redisTemplate.opsForValue().get(phone);
        if(!redisCode.equals(code) || StringUtils.isEmpty(redisCode)){
            throw new YyghException(20001, "验证码输入错误");
        }

        // 获取openid，判断是不是微信首次登录需要绑定手机号
        String openid = loginVo.getOpenid();
        UserInfo userInfo = null;
        if(StringUtils.isEmpty(openid)) { // 说明单纯就是手机号验证码登录
            // 4.根据手机号查询用户是否是首次登录，如果是首次登录，需要把信息添加到表中
            QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("phone", phone);
            userInfo = baseMapper.selectOne(queryWrapper);
            if(userInfo == null) {
                // 首次登录
                userInfo = new UserInfo();
                userInfo.setPhone(phone);
                baseMapper.insert(userInfo);
                userInfo.setStatus(1);
            }

        }else { // openid不为空，表示是走微信首次登录绑定手机号逻辑
            // 根据openid把数据查询出来[此时微信登录记录是肯定存在的]
            QueryWrapper<UserInfo> openIdWrapper = new QueryWrapper<>();
            openIdWrapper.eq("openid", openid);
            userInfo = baseMapper.selectOne(openIdWrapper);

            // 根据手机号进行查询，判断是不是之前已经有过手机号进行登录
            QueryWrapper<UserInfo> phoneWrapper = new QueryWrapper<>();
            phoneWrapper.eq("phone", phone);
            UserInfo userInfo2 = baseMapper.selectOne(phoneWrapper);

            if(userInfo2 == null){ // 表示之前没有手机号登录记录
                // 需要把当前微信号记录绑定上手机号
                userInfo.setPhone(phone);
                baseMapper.updateById(userInfo);
            }else { // 在微信首次登录之前，是有手机号登录记录的，需要进行合并
                // 需要把微信号的记录上的openid和nickname拷贝到手机号登录记录上
                userInfo2.setOpenid(userInfo.getOpenid());
                userInfo2.setNickName(userInfo.getNickName());
                baseMapper.updateById(userInfo2);
                // 删除之前的微信记录
                baseMapper.deleteById(userInfo.getId());
            }
        }

        // 5.判断用户当前的status状态，是正常还是锁定
        if(userInfo.getStatus() == 0) {
            throw new YyghException(20001, "当前用户已经被锁定");
        }

        // 6.返回用户数据
        Map<String, Object> result = new HashMap<>();
        // 设置返回值
        String name = userInfo.getName();
        if(StringUtils.isEmpty(name)) {
            name = userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getPhone();
        }
        result.put("name", name);
        String token = JwtHelper.createToken(userInfo.getId(), name);
        result.put("token", token);
        return result;
    }

    @Override
    public UserInfo getUserById(Long userId) {
        UserInfo userInfo = baseMapper.selectById(userId);
        userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus()));
        return userInfo;
    }

    @Override
    public boolean userAuth(Long userId, UserAuthVo userAuthVo) {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
        userInfo.setName(userAuthVo.getName());
        userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
        userInfo.setCertificatesType(userAuthVo.getCertificatesType());
        userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
        int count = baseMapper.updateById(userInfo);
        if(count > 0) {
            return true;
        }else {
            return false;
        }
    }

    @Override
    public Page<UserInfo> getUserInfoPage(Integer pageNum, Integer limit, UserInfoQueryVo userInfoQueryVo) {
        Page<UserInfo> page = new Page<>(pageNum, limit);
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        // 关键字模糊查询
        if(!StringUtils.isEmpty(userInfoQueryVo.getKeyword())) {
            // 名字和手机号都需要进行模糊查询
            queryWrapper.like("name", userInfoQueryVo.getKeyword()).or().eq("phone", userInfoQueryVo.getKeyword());
        }
        if(!StringUtils.isEmpty(userInfoQueryVo.getStatus())) {
            queryWrapper.eq("status", userInfoQueryVo.getStatus());
        }
        if(!StringUtils.isEmpty(userInfoQueryVo.getAuthStatus())) {
            queryWrapper.eq("auth_status", userInfoQueryVo.getAuthStatus());
        }
        // 起始时间，终止时间
        if(!StringUtils.isEmpty(userInfoQueryVo.getCreateTimeBegin())) {
            queryWrapper.gt("create_time", userInfoQueryVo.getCreateTimeBegin());
        }
        if(!StringUtils.isEmpty(userInfoQueryVo.getCreateTimeEnd())) {
            queryWrapper.lt("create_time", userInfoQueryVo.getCreateTimeEnd());
        }
        Page<UserInfo> userInfoPage = baseMapper.selectPage(page, queryWrapper);
        // 需要对认证状态和状态进行包装
        userInfoPage.getRecords().stream().forEach(item -> {
            this.packageUserInfo(item);
        });
        return userInfoPage;
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        if(status == 0 || status == 1) {
            UserInfo userInfo = baseMapper.selectById(id);
            userInfo.setStatus(status);
            baseMapper.updateById(userInfo);
        }else {
            throw new YyghException(20001, "status参数非法!");
        }
    }

    @Override
    public Map<String, Object> detail(Long id) {
        // 根据用户id查询用户信息
        UserInfo userInfo = baseMapper.selectById(id);
        // 根据用户id查询相关就诊人信息
        List<Patient> patients = patientService.findPatientListByUserId(id);
        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", userInfo);
        map.put("patients", patients);
        return map;
    }

    private void packageUserInfo(UserInfo item) {
        Integer status = item.getStatus();
        Integer authStatus = item.getAuthStatus();
        item.getParam().put("statusString", StatusEnum.getStatusStringByStatus(status));
        item.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(authStatus));
    }
}
